#'###########################################
#'                                          #
#'  ------------------------------------    #
#'  |     COIN     __                  |    #
#'  |            >(' )                 |    #
#'  |              )/                  |    #
#'  |             /  `----/            |    #
#'  |             \  ~=- /             |    #
#'  |   ~^~^~^~^~^~^~^~^~^~^~^~^~^~^   |    #
#'  ------------------------------------    #
#'                                          #
#'###########################################



#'###################################################################################
#'#                                                                                ##
#'#        Fonctions pour charger les donnees brutes ou les donnees Movebank       ##
#'#                                                                                ##
#'###################################################################################


#'#
#'# Load data and compute the error if specified
#'# 
loadData <- function(path, static=TRUE, locsclasses=c(3, 2, 1, 0, "A", "B"),
		raw=FALSE, compiled=TRUE, filtered=TRUE, ...) {
	if (static) {
		visibilities <- getStaticVisibilities(path)
    print(visibilities)
		data <- extractStaticData(visibilities, ...)
	} else {
		sessions <- getMobileSessions(path)
		data <- extractMobileData(sessions, ...)
	}
	
	#' on renvoie les donnees brutes
	if (raw) {
		return (data)
	}
	
	errors <- getErrors(data=data, static=static, filtered=filtered,
			compiled=compiled, locsClasses=locsclasses)
	
	return(errors)
}



#'#
#'# Compute errors between argos and gps data. Compile and filter the data if needed
#'# 
getErrors <- function (data, static, filtered=TRUE, compiled=TRUE, locsClasses=c(3, 2, 1, 0, "A", "B")) {
	if (exists("ARGOS_CLUSTER")){
		error <- parLapply(ARGOS_CLUSTER, data, getError)
	} else {
		error <- lapply(data, getError)
	}
	if (compiled) {
		if (static) {
			errors <- bindStaticErrors(error)
		} else {
			errors <- bindMobileErrors(error)
		}
		
		if (filtered) {
			#' We return only the LC in loclasses
			errors <- errors[LC %in% locsClasses]
			errors[, LC := factor(LC, levels=locsClasses)]
			setkey(errors, LC)
		}
		errors[, deployment := as.factor(deployment)]
		return (errors)
	}
	return (error)
}



#'#
#'# Load error file to avoid recomputing everytime!
#'# 
loadErrorsFile <- function (path, locsClasses=c(3, 2, 1, 0, "A", "B")) {
  errors <- data.table(read.delim(path, header=TRUE, stringsAsFactors=FALSE))
  #' We return only the LC in loclasses
  errors <- errors[LC %in% locsClasses]
  errors[, deployment := as.factor(deployment)]
  errors[, LC := factor(LC, levels=locsClasses)]
  errors[, time := as.POSIXct(time, tz="EST5EDT")]
  setkey(errors, deployment, time, LC)
  return (errors)
}


#'#
#'# rbind static errors
#'# 
bindStaticErrors <- function (error) {
	errors <- rbindlist(lapply(error, function(x) {return(x@data)}))
	setkey(errors, visibility, LC)
	return (errors)
}


#'#
#'# rbind mobile errors
#'# 
bindMobileErrors <- function (error) {
	errors <- do.call(rbind, error)
	errors <- errors[!is.na(gpsLong)]
	setkey(errors, LC)
	return (errors)
}


#'#
#'# Load data retrieved from the Movebank data
#'# 
loadMovebankData <- function (path, static=TRUE, mb_columns = c("timestamp",
				"location.long", "location.lat", "tag.local.identifier", "argos.lc",
				"individual.local.identifier", "study.name", "location.error.text"),
				locsclasses=c(3, 2, 1, 0, "A", "B")){
	
	data <- data.table(read.delim(path, stringsAsFactors=FALSE, sep=",")[, mb_columns])
	
	longlatErrors <- as.numeric(unlist(strsplit(data$location.error.text, ";")))
	
	setnames(data, names(data), MOVEBANK_COLUMN_NAMES[names(data)])
	
	data[, diffLong := longlatErrors[seq(1,length(longlatErrors), by = 2)]]
	data[, diffLat := longlatErrors[seq(2,length(longlatErrors), by = 2)]]
	
	if (static) {
		depl <- unlist(strsplit(data[, individual.local.identifier], "_"))
		data[, visibility := depl[seq(1,length(depl), by = 2)]]
		data[, session := depl[seq(2,length(depl), by = 2)]]
	} else {
    data[, deployment := as.factor(deployment)]
  }
  
	data[, distance := sqrt(diffLong^2 + diffLat^2)]
	data[, time := as.POSIXct(time, tz="GMT")]
	data[, time := as.POSIXct(format(time, tz="EST5EDT", usetz=TRUE))]
	
	data <- projectArgosCoordinates(data)
	
	errors.filtered <- data[LC %in% locsclasses]
	errors.filtered[, LC := factor(LC, levels=locsclasses)]
	setkey(errors.filtered, LC)
	
	return (errors.filtered)
}


loadSimulationFiles <- function(path, pattern, typeCode, ext=".csv", static=FALSE,
    write=FALSE, destName){
    files <- list.files(path, pattern=paste(".*", pattern, ".*", ext , sep=""))
    res <- vector(mode="list", length=length(files))
    for (i in 1:length(files)) {
        print(files[i])
        res[[i]] <- cbind(fread(file.path(path,files[i])),
            type=typeCode,
            iteration = i) 
    }
    tmp <- rbindlist(res)
    if (write) {
        write.csv(tmp, file.path(path, destName))
    }
    return (tmp)
}

compileRadiusData <- function(radius, statsCols, path) {
    print("Loading file")
    load(file.path(path, paste("HR_compare_radius", radius, "LC32_all.RData", sep="")))
    var <- paste("hrStatsRadius", radius, "LC32", sep="")
    get(var)[, deployment := as.factor(deployment)]
    get(var)[, iteration := as.factor(iteration)]
    
    print("Compiling stats")
    tmpStats <- compileHRStats(get(var), statsCols, statBy=quote(list(type, method, percent, deployment)))
    setkey(tmpStats, method, percent, deployment)
    tmpStats[, type := factor(type, levels=c("rad250", "rad500", "rad750",
                "rad1000","rad2500", "rad5000"))]
    print("Compiling graphs")
    tmpGraph <- NULL
    for (i in statsCols) {
        tmpGraph <- rbind(tmpGraph, cbind(get(var)[, meanICl3(.SD, i, byG2="deployment", byG3="iteration"), by=list(type, method, percent)], stat=i))
    }
    tmpGraph[, type := factor(type, levels=c("rad250", "rad500", "rad750",
                "rad1000","rad2500", "rad5000"))]
    tmpGraph[, stat := as.factor(stat)]
    
    rm(var)
    print("Exiting")
    return (list(stat=tmpStats, graph=tmpGraph))
}


saveArticleData <- function(data, destdir, static=TRUE){
    if (static) {
        write.csv(data@gps, paste(destdir, "/", "StaticTest_Visibility", data@visibility, "_GPS.csv",sep=""),
            row.names=FALSE)
        write.csv(data@argos, paste(destdir, "/", "StaticTest_Visibility", data@visibility, "_Argos.csv",sep=""), row.names=FALSE)
        
    } else {
      write.csv(data@gps, paste(destdir, "/", "MobileTrack_", data@deployment, "_GPS.csv",sep=""),
          row.names=FALSE)
      write.csv(data@argos, paste(destdir, "/", "MobileTrack_", data@deployment, "_Argos.csv",sep=""), row.names=FALSE)
    }
}